#include "head.h"

#define ADDRESS "tcp://localhost:1883"
#define CLIENTID "ExampleClientSub"
#define PAYLOAD "Hello World!"
#define QOS 1
#define TIMEOUT 10000L

MQTTClient client;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
MQTTClient_message pubmsg = MQTTClient_message_initializer;
MQTTClient_deliveryToken token;

volatile MQTTClient_deliveryToken deliveredtoken;

void delivered(void *context, MQTTClient_deliveryToken dt)
{
    printf("Message with token value %d delivery confirmed\n", dt);
    deliveredtoken = dt;
}

int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    char *payloadptr;

    payloadptr = message->payload;

    if (strcmp(topicName, TOPIC_DATA_DOWN) == 0)
    {
        char *p = NULL;
        cJSON *root = NULL;
        cJSON *item = NULL;

        root = cJSON_Parse(payloadptr);
        if (!root)
        {
            printf("Error before:[%s]\n", cJSON_GetErrorPtr());
        }

        item = cJSON_GetObjectItem(root, "type");
        p = cJSON_Print(item);

        item = cJSON_GetObjectItem(root, "limit");
        p = cJSON_Print(item);

        if (strcmp(p, "\"all\"") == 0)
        {
            //从共享内存中获取全部的数据
            if (mode == 0)
            {
                cJSON *root = read_shm_all(m0, modbus);
                mqtt_to_client(TOPIC_DATA_UP, cJSON_Print(root));
                printf("全部的数据\n");
            }
        }
        else
        {
            //采集部分的数据
        }
    }
    else if (strcmp(topicName, TOPIC_MODE_DOWN) == 0)
    {
        char *p = NULL;
        cJSON *root = NULL;
        cJSON *item = NULL;
        cJSON *send = cJSON_CreateObject();

        root = cJSON_Parse(payloadptr);
        if (!root)
        {
            printf("Error before:[%s]\n", cJSON_GetErrorPtr());
        }
        item = cJSON_GetObjectItem(root, "data");
        item = cJSON_GetObjectItem(item, "type");

        if (strcmp("0", cJSON_Print(item)) == 0) //不上报,客户端主动采集,刷新上报
        {
            mode = 0;
        }
        else if (strcmp("1", cJSON_Print(item)) == 0) //变化上报
        {
            mode = 1;
        }
        else if (strcmp("2", cJSON_Print(item)) == 0) //周期上报
        {
            item = cJSON_GetObjectItem(root, "data");
            item = cJSON_GetObjectItem(item, "period");
            Time = atoi(cJSON_Print(item));
            mode = 2;
        }

        printf("修改成功\n");
    }
    else if (strcmp(topicName, TOPIC_CONTROL_DOWN) == 0)
    {
        struct msgbuf send_buf, recv_buf;
        send_buf.mtype = 1;
        recv_buf.mtype = 1;

        strcpy(send_buf.mdata, payloadptr);

        char *p = NULL;
        int type, result, key;
        cJSON *root = NULL;
        cJSON *item = NULL;
        cJSON *recv_root = NULL;

        root = cJSON_Parse(payloadptr);
        if (!root)
        {
            printf("Error before:[%s]S\n", cJSON_GetErrorPtr());
        }

        item = cJSON_GetObjectItem(root, "type");
        type = atoi(cJSON_Print(item));

        item = cJSON_GetObjectItem(root, "data");
        item = cJSON_GetObjectItem(item, "key");
        key = atoi(cJSON_Print(item));

        if (type == 2)
        {
            if (key >= 0 && key <= 10)
            {
                if (msg_queue_send("m0_recv", &send_buf, sizeof(send_buf), 0) < 0)
                {
                    printf("msg_queue_send error\n");
                    return -1;
                }

                if (msg_queue_recv("m0_send", &recv_buf, sizeof(recv_buf), 0, 0) > 0)
                {

                    recv_root = recv_buf.mdata;
                    root = cJSON_Parse(recv_root);
                    item = cJSON_GetObjectItem(root, "result");
                    result = atoi(cJSON_Print(item));
                    if (result == 0)
                    {
                        printf("控制成功\n");
                    }
                    else
                    {
                        printf("控制失败\n");
                    }

                    // mqtt_to_client(TOPIC_CONTROL_UP,recv_root);
                }
            }
            else if (key >= 100 && key <= 150)
            {
                if (msg_queue_send("modbus_recv", &send_buf, sizeof(send_buf), 0) < 0)
                {
                    printf("msg_queue_send error\n");
                    return -1;
                }

                if (msg_queue_recv("modbus_send", &recv_buf, sizeof(recv_buf), 0, 0) > 0)
                {
                    recv_root = recv_buf.mdata;
                    root = cJSON_Parse(recv_root);
                    item = cJSON_GetObjectItem(root, "result");
                    result = atoi(cJSON_Print(item));
                    if (result == 0)
                    {
                        printf("控制成功\n");
                    }
                    else
                    {
                        printf("控制失败\n");
                    }

                    // mqtt_to_client(TOPIC_CONTROL_UP,recv_root);
                }
            }
        }
    }

    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    return 1;
}

void connlost(void *context, char *cause)
{
    printf("\nConnection lost\n");
    printf("     cause: %s\n", cause);
}

/*
*作者：王玉瑶
*时间：2022年2月11日
*函数功能：接收客户端发送的信息函数
 */
int client_to_mqtt()
{
    int rc;
    int ch;

    if (!MQTTClient_isConnected(client))
    {
        MQTTClient_create(&client, ADDRESS, CLIENTID,
                          MQTTCLIENT_PERSISTENCE_NONE, NULL);
        conn_opts.keepAliveInterval = 20;
        conn_opts.cleansession = 1;
    }
    MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered);

    if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to connect, return code %d\n", rc);
        exit(EXIT_FAILURE);
    }

    MQTTClient_subscribe(client, TOPIC_DATA_DOWN, QOS);
    MQTTClient_subscribe(client, TOPIC_CONTROL_DOWN, QOS);
    MQTTClient_subscribe(client, TOPIC_MODE_DOWN, QOS);

    do
    {
        ch = getchar();
    } while (ch != 'Q' && ch != 'q');

    MQTTClient_unsubscribe(client, TOPIC_DATA_DOWN);
    MQTTClient_unsubscribe(client, TOPIC_CONTROL_DOWN);
    MQTTClient_unsubscribe(client, TOPIC_MODE_DOWN);
    MQTTClient_disconnect(client, 10000);
    MQTTClient_destroy(&client);
    return rc;
}

/*
*作者：王玉瑶
*时间：2022年2月11日
*函数功能：mqtt给客户端发送信息的函数
 */
int mqtt_to_client(char *topical, cJSON *root)
{

    int rc;
    if (!MQTTClient_isConnected(client))
    {
        MQTTClient_create(&client, ADDRESS, CLIENTID,
                          MQTTCLIENT_PERSISTENCE_NONE, NULL);
        conn_opts.keepAliveInterval = 20;
        conn_opts.cleansession = 1;
        // if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
        // {
        //     printf("Failed to connect, return code %d\n", rc);
        //     exit(EXIT_FAILURE);
        // }
    }

    pubmsg.payload = root;
    pubmsg.payloadlen = (int)strlen(root);
    pubmsg.qos = QOS;
    pubmsg.retained = 0;
    MQTTClient_publishMessage(client, topical, &pubmsg, &token);

    // rc = MQTTClient_waitForCompletion(client, token, TIMEOUT);
    // MQTTClient_disconnect(client, 10000);
    // MQTTClient_destroy(&client);
    return rc;
}
